package ar.edu.itba.it.cg.grupo01.state;

import org.fenggui.event.ButtonPressedEvent;
import org.fenggui.event.IButtonPressedListener;

import ar.edu.itba.it.cg.grupo01.game.BaseGame;
import ar.edu.itba.it.cg.grupo01.menu.Menu;
import ar.edu.itba.it.cg.grupo01.vehicle.Hud;

import com.jme.bounding.BoundingBox;
import com.jme.input.InputHandler;
import com.jme.math.Vector3f;
import com.jme.renderer.ColorRGBA;
import com.jme.renderer.Renderer;
import com.jme.scene.Node;
import com.jme.scene.Spatial;
import com.jme.scene.shape.Box;
import com.jme.scene.state.BlendState;
import com.jme.system.DisplaySystem;
import com.jme.util.Timer;
import com.jmex.scene.TimedLifeController;

public class MenuState extends MyGameState
        implements IButtonPressedListener {

    public Menu getMenu() {
        return menu;
    }

    private Menu menu;
    private BaseGame game;

    private boolean finished = false;
    private final String name = "MENU STATE";
    private GameStateType lastState;
    private Node rootNode;
    
    private float alfa = 0.0f;
    private final float deltaAlfa = 0.01f;
    private final float maxAlfa = 0.5f;
    private final float minAlfa = 0.0f;
    private final long delayFade = 10;
    private boolean fading = true;
    private boolean mustFadeOut = true;
	private boolean leaving = false;
	
	public MenuState(Node rootNode, InputHandler input, BaseGame game,Hud hud) {

        super(GameStateType.MENU, rootNode, input,hud);
        this.game = game;
        this.menu = new Menu();
        this.rootNode = rootNode;
        menu.setNewGameListener(this);
        lastState = GameStateType.PLAY;
        
    }

    
    private void deleteBlackEnd(){
    	Node aNode = null;
    	if((aNode = (Node) rootNode.getChild("faderNode")) != null){
    	aNode.detachAllChildren();
    	aNode.updateRenderState();
    	rootNode.detachChildNamed("faderNode");
    	rootNode.updateRenderState();
    	}
    }
    
    private void createBlackEnd(Node rootNode, float alfa)
    {
    	Box blackBox = new Box("fader", game.getCamera().getCamera().getLocation(), 30,30,30);

		blackBox.setSolidColor(new ColorRGBA(0, 0, 0, alfa));

		BlendState faderBlending = DisplaySystem.getDisplaySystem().getRenderer()
				.createBlendState();
		faderBlending.setBlendEnabled(true);
		faderBlending.setSourceFunction(BlendState.SourceFunction.SourceAlpha);
		faderBlending
				.setDestinationFunction(BlendState.DestinationFunction.OneMinusSourceAlpha);
		faderBlending.setTestEnabled(false);
		faderBlending.setTestFunction(BlendState.TestFunction.GreaterThanOrEqualTo);
		faderBlending.setEnabled(true);

		Node forceFieldNode = new Node("faderNode");
		
		forceFieldNode.setRenderQueueMode(Renderer.QUEUE_OPAQUE);
		forceFieldNode.attachChild(blackBox);
		
		forceFieldNode.setModelBound(new BoundingBox());
		forceFieldNode.updateModelBound();
		
		blackBox.setRenderState(faderBlending);

		forceFieldNode.updateRenderState();
		
		rootNode.attachChild(forceFieldNode);
    }
 
    public void enterState() {
		System.out.println("Entered MENU STATE");
		this.game.pauseGame();

		finished = false;
		this.menu.setActive(true);

		this.alfa = 0f;
		this.fading = true;
		this.mustFadeOut = true;
		this.leaving = false;
    }



	public void leaveState() {

        System.out.println("Left MENU STATE");
        
     
        this.game.unpauseGame();
        this.menu.setActive(false);
        this.fading = false;
    }

    public String getName() {

        return this.name;
    }

    @Override
    public GameStateType update(Timer timer) {

		fadeIn(timer);
		fadeOut(timer);
		
        if(!finished) {
            return getType();
        }
        else {
        	leaving = true;
			if (mustFadeOut)
				return getType();
			else
				return lastState;
        }
    }

	private void fadeOut(Timer timer) {
		if (mustFadeOut && leaving) {
			deleteBlackEnd();
			createBlackEnd(rootNode, alfa);
			alfa -= deltaAlfa;
		
			System.out.println("fading in");
			System.out.println("nuevo alfa" + alfa);
			
			delayExecution();

			if (alfa < minAlfa){
				mustFadeOut = false;
				deleteBlackEnd();
			}
			super.update(timer);
		}
	}

	private void delayExecution() {
		try {
			Thread.sleep(delayFade);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	private void fadeIn(Timer timer) {
		if (fading) {
			
			deleteBlackEnd();
			createBlackEnd(rootNode, alfa);
			alfa += deltaAlfa;
			
			System.out.println("fading in");
			System.out.println("nuevo alfa"+alfa);
			
			delayExecution();
		
			if(alfa > maxAlfa)
				fading = false;
			
			super.update(timer);
		}
	}

    public void render() {
    	if(!fading)
    		menu.render();
    }

    
    public void buttonPressed(ButtonPressedEvent event) {

        lastState = GameStateType.PLAY;
        finished = true;
        this.menu.setStarted(true);
        if (menu.isReset())
            hud.playCountdown(input);
    }
    

}
